/*! 
 * Implementation file for a triangle shape (used for complex meshes like terrains).
 *
 * \author Devis Rossini
 * \date 22 April 2012
 */
#include "PhxTriangle.h"

using namespace phx;

Vector3 Triangle::CalculateNormal()
{
	Vector3 v0 = mTriangleVertex0.mVertex;
	Vector3 v1 = mTriangleVertex1.mVertex;
	Vector3 v2 = mTriangleVertex2.mVertex;

	Vector3 a = v2 - v0;
	Vector3 b = v1 - v0;

	Vector3 temp = a.CrossProduct(b);
	temp.Normalise();
	return temp;
}

Vector3 Triangle::GetNormal() const
{
	return mNormal;
}

Vector3 Triangle::GetVertex0() const
{
	return mTriangleVertex0.mVertex;
}

Vector3 Triangle::GetVertex1() const
{
	return mTriangleVertex1.mVertex;
}

Vector3 Triangle::GetVertex2() const
{
	return mTriangleVertex2.mVertex;
}

Vector3 Triangle::PointProjectionOnPlane(const Vector3& iPoint) const
{
	real temp = mNormal.DotProduct(iPoint - mTriangleVertex0.mVertex);
	temp /= mNormal.DotProduct(mNormal);
	Vector3 projection = iPoint - (mNormal * temp);

	return projection;	
}

bool Triangle::IsProjectionInTriangle(const Vector3& iPoint) const
{
	Vector3 v0 = mTriangleVertex0.mVertex;
	Vector3 v1 = mTriangleVertex1.mVertex;
	Vector3 v2 = mTriangleVertex2.mVertex;

	Vector3 edge0 = v1 - v0;
	Vector3 edge1 = v2 - v0;
	Vector3 edge2 = iPoint - v0;

	float d00 = edge0.DotProduct(edge0);
	float d01 = edge0.DotProduct(edge1);
	float d11 = edge1.DotProduct(edge1);
	float d20 = edge2.DotProduct(edge0);
	float d21 = edge2.DotProduct(edge1);
	float den = d00 * d11 - d01 * d01;
	float v = (d11 * d20 - d01 * d21) / den;
	float w = (d00 * d21 - d01 * d20) / den;
	float u = 1.0f - v - w;

	return v >= 0.0f && w >= 0.0f && (v + w) <= 1.0f;
}